<template>
  <a-row :gutter="[16, 16]" class="search">
    <a-col :span="4">
      <a-input v-model:value="searchInfo.title" placeholder="博客标题" />
    </a-col>
    <a-col :span="4">
      <a-select
        v-model:value="searchInfo.sort"
        placeholder="博客分类"
        style="width: 100%"
      >
        <a-select-option
          v-for="item of sortList"
          :key="item.id"
          :value="item.id"
          >{{ item.name }}
        </a-select-option>
      </a-select>
    </a-col>
    <a-col :span="4" class="btn">
      <a-button :icon="h(SearchOutlined)" type="primary" @click="search"
        >搜索
      </a-button>
      <a-button :icon="h(RedoOutlined)" @click="restSearch">重置</a-button>
    </a-col>
  </a-row>

  <a-row style="display: flex; align-items: center; gap: 15px; margin: 15px 0">
    <a-button type="primary" @click="add">新增</a-button>
    <a-popconfirm
      cancel-text="取消"
      ok-text="删除"
      title="是否删除?"
      @confirm="deleteFunction(toRaw(state.selectedRowKeys))"
    >
      <a-button danger>删除</a-button>
    </a-popconfirm>

    <a-button>导出</a-button>
  </a-row>
  <a-table
    :columns="columns"
    :data-source="TableData"
    :loading="loading"
    :pagination="pagination"
    :row-selection="{
      selectedRowKeys: state.selectedRowKeys,
      onChange: onSelectChange,
    }"
    style="height: calc(100vh - 270px)"
    @change="handleTableChange"
  >
    <template #bodyCell="{ column, record }">
      <template v-if="column.key === 'title'">
        <p class="table-label-title">{{ record.title }}</p>
      </template>

      <template v-if="column.key === 'cover'">
        <a-image :src="record.cover" :width="200" style="height: 60px" />
      </template>

      <template v-if="column.key === 'editType'">
        <span>
          <a-tag v-if="record.editType === 1" color="success">富文本</a-tag>
          <a-tag v-else color="processing">MarkDown</a-tag>
        </span>
      </template>

      <template v-if="column.key === 'type'">
        <span>
          <i v-if="record.type === 1">原创</i>
          <i v-else>转载</i>
        </span>
      </template>

      <template v-if="column.key === 'status'">
        <span>
          <a-tag v-if="record.status === 1" color="geekblue">正常</a-tag>
          <a-tag v-else color="error">注销</a-tag>
        </span>
      </template>

      <template v-if="column.key === 'pub_date'">
        <span>
          {{ dayjs(record.pub_date).format("YYYY-MM-DD HH:mm:ss") }}
        </span>
      </template>
      <template v-if="column.key === 'up_date'">
        <span>
          {{ dayjs(record.up_date).format("YYYY-MM-DD HH:mm:ss") }}
        </span>
      </template>

      <template v-if="column.key === 'action'">
        <span style="display: flex; align-items: center; gap: 15px">
          <a-button type="primary" @click="edit(record)">
            <template #icon>
              <EditOutlined />
            </template>
          </a-button>
          <a-popconfirm
            cancel-text="取消"
            ok-text="删除"
            title="是否删除该博客?"
            @confirm="deleteFunction(record.id)"
          >
            <a-button danger>
              <template #icon>
                <DeleteOutlined />
              </template>
            </a-button>
          </a-popconfirm>
          <a-button @click="showModal(record)">
            <template #icon>
              <EyeOutlined />
            </template>
          </a-button>
          <a-popconfirm
            cancel-text="取消"
            ok-text="置顶"
            title="是否置顶?"
            @confirm="setTopBlog(record)"
          >
            <a-button :class="record.isTop ? 'topActive' : ''">
              <template #icon>
                <PushpinOutlined />
              </template>
            </a-button>
          </a-popconfirm>
        </span>
      </template>
    </template>
  </a-table>

  <!--修改-->
  <Drawer
    ref="drawerRef"
    title="更新博客"
    @closeDrawer="closeDrawer"
    @submitDrawer="submitDrawer"
  >
    <a-form
      ref="formRef"
      :label-col="labelCol"
      :model="formState"
      :rules="rules"
      :wrapper-col="wrapperCol"
    >
      <a-row justify="center">
        <a-col :span="12">
          <a-form-item ref="title" label="博客标题" name="title">
            <a-input v-model:value="formState.title" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item label="博客分类" name="sort">
            <a-select
              v-model:value="formState.sort"
              placeholder="请选择你的博客分类"
            >
              <a-select-option
                v-for="item of sortList"
                :key="item.id"
                :value="item.id"
                >{{ item.name }}
              </a-select-option>
            </a-select>
          </a-form-item>
        </a-col>
      </a-row>
      <a-row justify="center">
        <a-col :span="12">
          <a-form-item label="博客类型" name="type">
            <a-radio-group v-model:value="formState.type">
              <a-radio :value="1">原创</a-radio>
              <a-radio :value="2">转载</a-radio>
            </a-radio-group>
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item label="博客摘要" name="summary">
            <a-input v-model:value="formState.summary" />
          </a-form-item>
        </a-col>
      </a-row>

      <a-form-item label="博客封面" name="cover">
        <Upload v-model:FileList="formState.cover"></Upload>
      </a-form-item>
    </a-form>
    <!--  编辑器选项-->
    <template v-if="formState['editType'] === 1">
      <WangEditor
        v-model:content="formState.content"
        style="min-height: calc(100vh - 200px)"
      ></WangEditor>
    </template>
    <template v-else>
      <MarkDown
        v-model:content="formState.content"
        style="min-height: calc(100vh - 200px)"
      ></MarkDown>
    </template>
  </Drawer>

  <!--  预览-->
  <a-modal
    v-model:open="open"
    footer=""
    heigth="100%"
    width="100%"
    wrap-class-name="full-modal"
  >
    <div class="blogPreview">
      <h2 class="title">{{ previewInfo.title }}</h2>
      <div class="info">
        <span style="color: #333">
          <span class="iconfont icon-yonghu iconBasic"></span>
          {{ previewInfo.user.username }}
        </span>
        <span style="color: #409eff">
          <span class="iconfont icon-fenlei iconBasic"></span>
          {{ previewInfo.sort_name }}
        </span>
        <span>
          <span class="iconfont icon-xihuan iconBasic"></span>
          {{ previewInfo.likes }}
        </span>
        <span>
          <span class="iconfont icon-pinglun iconBasic"></span>
          {{ previewInfo.comments }}
        </span>
        <time>
          {{ dayjs(previewInfo.pub_date).format("YYYY-MM-DD HH:mm:ss") }}
        </time>
      </div>
      <div ref="containerRef" class="content">
        <template v-if="previewInfo['editType'] === 1">
          <WangEditor
            v-model:content="previewInfo.content"
            :height="'auto'"
            :preview="true"
          ></WangEditor>
        </template>
        <template v-else>
          <div class="preview">
            <MdPreview :editorId="id" :modelValue="previewInfo.content" />
            <a-affix :offset-top="0" :target="() => containerRef">
              <h1>目录</h1>
              <MdCatalog
                :editorId="id"
                :scrollElement="scrollElement"
                class="catalog"
                style="max-height: 460px; overflow: auto"
              />
            </a-affix>
          </div>
        </template>
      </div>
    </div>
  </a-modal>
</template>

<script setup>
import {
  DeleteOutlined,
  EditOutlined,
  EyeOutlined,
  PushpinOutlined,
  RedoOutlined,
  SearchOutlined,
} from "@ant-design/icons-vue";
import { computed, getCurrentInstance, h, reactive, ref, toRaw } from "vue";
import { delBlog, getAllBlog, topBlog, updateBlog } from "@/api/blog.js";
import dayjs from "dayjs";
import { userStore } from "@/store/modules/user.js";
import router from "@/router/index.js";
import { message } from "ant-design-vue";
import Drawer from "@/components/Drawer/index.vue";
import Upload from "@/components/Upload/index.vue";
import MarkDown from "@/components/MarkDown/index.vue";
import WangEditor from "@/components/WangEditor/index.vue";
import { MdCatalog, MdPreview } from "md-editor-v3";
import { sortAll } from "@/api/sort.js";
import "md-editor-v3/lib/preview.css";
const scrollElement = document.documentElement;
const id = "preview-only";
const user = userStore();
const initSearch = {
  title: "",
  sort: undefined,
};
let searchInfo = reactive({ ...initSearch });

let TableData = ref([]);
// 表单
const formState = reactive({
  sort: "",
  cover: "",
  type: "",
  summary: "",
  title: "",
  editType: "",
  content: "",
});
// 分类数据
const sortList = ref([]);

// ref
const drawerRef = ref();
const uploadRef = ref();
const formRef = ref();
const containerRef = ref();

let loading = ref(true);
const state = reactive({
  selectedRowKeys: [],
});
let open = ref(false);
let total = ref(0);
let current = ref(0);
let pageSize = ref(0);
let previewInfo = ref({});

// 配置项
const wrapperCol = {
  span: 13,
};
const labelCol = {
  span: "100px",
};
const rules = {
  title: [
    {
      required: true,
      message: "博客标题不能为空",
      trigger: "change",
    },
  ],
  sort: [
    {
      required: true,
      message: "请选择一个分类",
      trigger: "change",
    },
  ],
  summary: [
    {
      required: true,
      message: "博客摘要不能为空",
      trigger: "change",
    },
  ],
  type: [
    {
      required: true,
      message: "博客类型不能为空",
      trigger: "change",
    },
  ],
};
const columns = [
  {
    title: "封面",
    key: "cover",
    dataIndex: "cover",
    width: 180,
  },
  {
    title: "文章标题",
    key: "title",
    dataIndex: "title",
  },
  {
    title: "分类",
    key: "sort_name",
    dataIndex: "sort_name",
    width: 200,
  },
  {
    title: "编辑器",
    key: "editType",
    dataIndex: "editType",
  },
  {
    title: "类型",
    key: "type",
    dataIndex: "type",
    width: 150,
  },
  {
    title: "状态",
    key: "status",
    dataIndex: "status",
    width: 150,
  },
  {
    title: "发布时间",
    key: "pub_date",
    dataIndex: "pub_date",
    width: 300,
  },
  {
    title: "更新时间",
    key: "up_date",
    dataIndex: "up_date",
    width: 300,
  },
  {
    title: "操作",
    key: "action",
    width: 300,
  },
];

// 查询博客
const search = async () => {
  loading.value = true;
  if (searchInfo.title === "" && searchInfo.sort === undefined) {
    message.error("查询不能为空");
    return;
  }
  let info = toRaw(searchInfo);
  await get_TableData({ ...info });
};

// 重置查询
const restSearch = async () => {
  loading.value = true;
  Object.assign(searchInfo, initSearch);
  await get_TableData();
};

// 查询table数据
const get_TableData = async (params) => {
  loading.value = true;
  let res = await getAllBlog({ id: user.user_id, ...params });
  if (!res) return;
  if (res.status === 400) {
    message.error(res.data);
    return;
  }
  TableData.value = res.data.map((item) => ({ ...item, key: item.id }));
  total.value = res.total;
  current.value = res.page;
  pageSize.value = res.pageSize;
  loading.value = false;
};

// 获取所有分类
const get_sortAll = async () => {
  let res = await sortAll();
  if (!res) return;
  sortList.value = res.data;
};

// 勾选删除id
const onSelectChange = (selectedRowKeys) => {
  state.selectedRowKeys = selectedRowKeys;
};

// 发布博客
const add = () => {
  router.push("/blog/add");
};

// 删除
const deleteFunction = async (params) => {
  let res = await delBlog({ id: params });
  await get_TableData();
  message.success(res.data);
};

// 修改博客
const edit = (record) => {
  drawerRef.value.showDrawer();
  setTimeout(() => {
    handeEditData(record);
  }, 0);
};

// 处理表单回显数据
const handeEditData = (obj) => {
  for (let key in obj) {
    if (key === "user") obj["user"] = obj[key]?.id;
    if (key === "sort_id") formState["sort"] = obj[key];
    formState[key] = obj[key];
  }
  if (uploadRef.value) {
    uploadRef.value.fileList = [];
    uploadRef.value.fileList.push({
      url: import.meta.env.VITE_APP_PROXY_TARGET + obj["cover"],
    });
  }
};

// 重置表单
const closeDrawer = () => {
  formRef.value.resetFields();
};

// 提交表单
const submitDrawer = async () => {
  let res = await updateBlog(toRaw(formState));
  await get_TableData();
  if (res.status === 400) message.success(res.data);
  else message.success(res.data);
};

// 置顶博客
const setTopBlog = async (data) => {
  const isTop = !Boolean(data.isTop);
  let res = await topBlog({ isTop: isTop, id: data.id });
  if (!res) return;
  await get_TableData();
  message.success(res.data);
};

// 分页
const pagination = computed(() => ({
  total: total.value,
  current: current.value,
  pageSize: pageSize.value,
  showTotal: (total) => `总共 ${total} 项`,
  defaultPageSize: 10,
  pageSizeOptions: ["5", "10", "15", "20"], // 可不设置使用默认
}));
// 点击分页
const handleTableChange = (pag, filters, sorter) => {
  current.value = pag.current;
  pageSize.value = pag.pageSize;
  get_TableData({ page: current.value, pageSize: pageSize.value });
};

// 打开预览弹窗
const showModal = (data) => {
  previewInfo.value = data;
  open.value = true;
};

get_TableData();
get_sortAll();
</script>

<style lang="scss" scoped>
.search {
  .btn {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-evenly;
    gap: 15px;
  }
}

.blogPreview {
  width: 100%;

  .title {
    color: #252933;
    font-size: 30px;
    text-align: center;
    font-weight: 600;
  }

  .info {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 20px;
    color: #8a919f;

    .iconBasic {
      display: inline-block;
      font-size: 16px;
      margin: 0 5px;
    }
  }

  .content {
    margin-top: 20px;
    height: calc(100vh - 150px);
    overflow-y: scroll;
    padding: 0 20px;

    .preview {
      width: 100%;
      display: grid;
      grid-template-columns: auto 300px;
      gap: 15px;
      padding: 15px;

      h1 {
        font-size: 22px;
        font-weight: 600;
        padding-bottom: 10px;
        border-bottom: 1px solid #eaeaea;
      }
    }
  }
}

.topActive {
  background-color: #63a35c;
  color: #fff;
}

.table-label-title {
  width: 150px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>
